package org.openkanban.client.util;

import java.util.HashSet;
import java.util.Set;

import org.openkanban.shared.dto.ActivityDto;
import org.openkanban.shared.dto.KanbanDto;
import org.openkanban.shared.dto.UserDto;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.smartgwt.client.util.JSON;

/**
 * Utility class to get values out of a JSON String.
 * 
 */
public abstract class JsonConverter {

    public static String getStringValueOrNull(String eingabe, String dtoAttributeName) {
	return getStringValueOrNull(new JSONObject(JSON.decode(eingabe)), dtoAttributeName);
    }

    public static String getStringValueOrNull(JSONObject jso, String dtoAttributeName) {
	if (jso != null) {
	    if (jso.containsKey(dtoAttributeName)) {
		JSONValue value = jso.get(dtoAttributeName);
		if (value != null) {
		    JSONString valueString = value.isString();
		    if (valueString != null) {
			return valueString.stringValue();
		    }
		}
	    }
	}
	return null;
    }

    public static Long getLongValueOrNull(String eingabe, String dtoAttributeName) {
	return getLongValueOrNull(new JSONObject(JSON.decode(eingabe)), dtoAttributeName);
    }

    public static Long getLongValueOrNull(JSONObject jso, String dtoAttributeName) {
	if (jso != null) {
	    if (jso.containsKey(dtoAttributeName)) {
		JSONValue value = jso.get(dtoAttributeName);
		if (value != null) {
		    JSONNumber valueNumber = value.isNumber();
		    if (valueNumber != null) {
			return (long) valueNumber.doubleValue();
		    }
		}
	    }
	}
	return null;
    }

    public static Integer getIntegerValueOrNull(String eingabe, String dtoAttributeName) {
	return getIntegerValueOrNull(new JSONObject(JSON.decode(eingabe)), dtoAttributeName);
    }

    public static Integer getIntegerValueOrNull(JSONObject jso, String dtoAttributeName) {
	if (jso != null) {
	    if (jso.containsKey(dtoAttributeName)) {
		JSONValue value = jso.get(dtoAttributeName);
		if (value != null) {
		    JSONNumber valueNumber = value.isNumber();
		    if (valueNumber != null) {
			return (int) valueNumber.doubleValue();
		    }
		}
	    }
	}
	return null;
    }

    public static Boolean getBooleanValueOrNull(String eingabe, String dtoAttributeName) {
	return getBooleanValueOrNull(new JSONObject(JSON.decode(eingabe)), dtoAttributeName);
    }

    public static Boolean getBooleanValueOrNull(JSONObject jso, String dtoAttributeName) {
	if (jso != null) {
	    if (jso.containsKey(dtoAttributeName)) {
		JSONValue value = jso.get(dtoAttributeName);
		if (value != null) {
		    JSONBoolean valueBoolean = value.isBoolean();
		    if (valueBoolean != null) {
			return (boolean) valueBoolean.booleanValue();
		    }
		}
	    }
	}
	return null;
    }

    public static <T> Set<T> getObjectsAsSet(String json, String dtoAttribute, Class<T> clazz) {
	Set<T> setToReturn = new HashSet<T>();
	JSONObject jso = new JSONObject(JSON.decode(json));
	JSONArray jsa = jso.get(dtoAttribute).isArray();
	if (jsa != null) {
	    for (int i = 0; i < jsa.size(); i++) {
		T object = null;
		String objectJson = jsa.get(i).isObject().toString();
		if (clazz == ActivityDto.class) {
		    object = (T) new ActivityDto(objectJson);
		} else if (clazz == KanbanDto.class) {
		    object = (T) new KanbanDto(objectJson);
		} else if (clazz == UserDto.class) {
		    object = (T) new UserDto(objectJson);
		}
		if (object != null) {
		    setToReturn.add(object);
		}
	    }
	}

	return setToReturn;
    }
}
